package com.tuanzi.loan.business.service.sms.el.evaluator;

import java.util.List;
import java.util.Set;
import java.util.function.Consumer;
import java.util.function.Predicate;
import java.util.stream.Collectors;

import org.apache.commons.collections4.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import com.google.common.collect.Sets;
import com.tuanzi.loan.business.entity.common.UserInstallDetail;
import com.tuanzi.loan.business.service.family.UserBlacklistService;
import com.tuanzi.loan.business.service.sms.el.AbstractEvaluator;
import com.tuanzi.loan.business.service.sms.vo.SmsSearchResponse;
import com.tuanzi.loan.vo.view.family.UserValidateView;

/**
 * 这里为什么写法这么诡异, 是因为如果一次把"用户安装App列表","点金/百度信用信息" 缓存到内存,内存不够支持这么多的数据,
 * 但如果不进行缓存,每个电话号码都进行一次数据库查询,导致性能非常慢, 所以折中的办法是分批进行缓存和校验,每次校验完一批就将缓存清除 Ray
 */
@Component
public class EliminateBlackListEvaluator extends AbstractEvaluator {

	@Autowired
	private UserBlacklistService userBlacklistService;

	private static final String TELECOM_OPERATORS_BLACK_LIST_TYPE = "1";

	public EliminateBlackListEvaluator telecomOperatorsBlackList() {

		List<String> mobnums = getMatchRuleContext().getResponses().stream().map(x -> x.getPhone()).collect(Collectors.toList());

		Set<String> blackListMobnums = Sets.newHashSet(userBlacklistService.findMobnumsBy(mobnums, TELECOM_OPERATORS_BLACK_LIST_TYPE));
		getMatchRuleContext().setResponses(getMatchRuleContext().getResponses().stream().filter(x -> !blackListMobnums.contains(x.getPhone())).collect(Collectors.toList()));

		return this;
	}

	public EliminateBlackListEvaluator notMatchRegion() {
		return this;
	}

	public EliminateBlackListEvaluator pdlUser() {

		Consumer<List<SmsSearchResponse>> prepareAction = (List<SmsSearchResponse> subResponses) -> {
			getMatchRuleContext().cacheBaiduJR(getResponsePhone(subResponses));
			getMatchRuleContext().cacheDianjin(getResponsePhone(subResponses));
			getMatchRuleContext().cacheUserInstallDetails(getResponsePhoneIds(subResponses));
		};

		Predicate<SmsSearchResponse> filter = (SmsSearchResponse response) -> {
			Integer pdlAppCount = 0;
			Integer loanAppCount = 0;
			UserInstallDetail userInstallDetail = getMatchRuleContext().getUserInstallDetailWithCache(response.getPhoneId());
			if (userInstallDetail != null) {
				pdlAppCount = userInstallDetail.getPdlAppCount();
				loanAppCount = userInstallDetail.getLoanAppCount();
			}

			boolean result = (response.getSesamePoint() != null && response.getSesamePoint() < 550) || loanAppCount > 7 || pdlAppCount > 3
					|| getMatchRuleContext().getDianjinWithCache(response.getPhone()).stream().map(y -> y.getResults()).flatMap(y -> y.stream())
							.filter(y -> "EMR002".equalsIgnoreCase(y.getOriginalType())).map(UserValidateView.DianJinResult::getPlatformCode).distinct().count() > 5;

			return !result;
		};

		splitRun(prepareAction, filter);

		return this;
	}

	public EliminateBlackListEvaluator overdueUser() {

		Consumer<List<SmsSearchResponse>> prepareAction = (List<SmsSearchResponse> subResponses) -> {
			getMatchRuleContext().cacheDianjin(getResponsePhone(subResponses));
		};

		Predicate<SmsSearchResponse> filter = (SmsSearchResponse response) -> {
			for (UserValidateView.DianJin dianJin : getMatchRuleContext().getDianjinWithCache(response.getPhone())) {

				if (dianJin != null && CollectionUtils.isNotEmpty(dianJin.getResults())) {
					for (UserValidateView.DianJinResult result : dianJin.getResults()) {
						if ("EMR012".equalsIgnoreCase(result.getOriginalType()) || "EMR013".equalsIgnoreCase(result.getOriginalType())) {
							return false;
						}
					}
				}
			}
			return true;
		};

		splitRun(prepareAction, filter);
		return this;
	}

	public EliminateBlackListEvaluator baiduBlackListA() {
		getResponseWithCheckBlackLevel("A");
		return this;
	}

	public EliminateBlackListEvaluator baiduBlackListB() {
		getResponseWithCheckBlackLevel("B");
		return this;
	}

	public EliminateBlackListEvaluator baiduBlackListC() {
		getResponseWithCheckBlackLevel("C");
		return this;
	}

	public EliminateBlackListEvaluator baiduBlackListD() {
		getResponseWithCheckBlackLevel("D");
		return this;
	}

	private void getResponseWithCheckBlackLevel(String blackLevel) {

		Consumer<List<SmsSearchResponse>> prepareAction = (List<SmsSearchResponse> subResponses) -> {
			getMatchRuleContext().cacheBaiduJR(getResponsePhone(subResponses));
		};

		Predicate<SmsSearchResponse> filter = (SmsSearchResponse response) -> !checkBlackLevel(blackLevel, response);

		splitRun(prepareAction, filter);
	}

	private boolean checkBlackLevel(String blackLevel, SmsSearchResponse response) {

		for (UserValidateView.BaiduJR baiduJR : getMatchRuleContext().getBaiduJRWithCache(response.getPhone())) {

			if (blackLevel.equalsIgnoreCase(baiduJR.getBlackLevel())) {
				return true;
			}
		}

		return false;
	}

}
